#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
CodeBuddy完整登录流程脚本
基于用户提供的成功登录请求序列
"""

import requests
from urllib.parse import unquote, parse_qs, urlparse
import re
from bs4 import BeautifulSoup
import json
import base64

class CompleteLoginFlow:
    def __init__(self):
        self.session = requests.Session()
        self.setup_headers()
        
    def setup_headers(self):
        """设置浏览器请求头"""
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Accept-Encoding": "gzip, deflate, br",
            "DNT": "1",
            "Connection": "keep-alive",
            "Upgrade-Insecure-Requests": "1",
            "sec-ch-ua": '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"Windows"'
        })
    
    def analyze_provided_requests(self):
        """分析用户提供的成功登录请求序列"""
        print("🔍 分析提供的成功登录请求序列...")
        
        # 第一个请求：登录认证
        login_url = "https://www.codebuddy.ai/auth/realms/copilot/login-actions/authenticate?session_code=Tdcyuv1-OXlc_LaG7mvy73BkW3Q7wL_lmG1aFpg6kLI&execution=fddd3124-02c5-4e2e-9e11-2849f14b804f&client_id=console&tab_id=NeO5UYGnaB8&client_data=eyJydSI6Imh0dHBzOi8vd3d3LmNvZGVidWRkeS5haS9jb25zb2xlL2FjY291bnRzLy5hcGlzaXgvcmVkaXJlY3QiLCJydCI6ImNvZGUiLCJzdCI6ImI0M2IxN2NkN2JjZWQ3N2I3NTEzY2Q1YzcyYjI4OTRkIn0"
        
        # 解析URL参数
        parsed_url = urlparse(login_url)
        params = parse_qs(parsed_url.query)
        
        print("📋 第一个请求 - 登录认证:")
        print(f"  URL: {login_url}")
        print("  参数:")
        for key, value in params.items():
            print(f"    - {key}: {value[0]}")
        
        # 解码client_data
        try:
            client_data_encoded = params.get('client_data', [''])[0]
            if client_data_encoded:
                # 添加padding以确保正确解码
                padding = 4 - len(client_data_encoded) % 4
                if padding != 4:
                    client_data_encoded += '=' * padding
                
                client_data_decoded = base64.b64decode(client_data_encoded).decode('utf-8')
                client_data_json = json.loads(client_data_decoded)
                print("  Client Data解码:")
                for key, value in client_data_json.items():
                    print(f"    - {key}: {value}")
        except Exception as e:
            print(f"  ❌ Client Data解码失败: {e}")
        
        # 第二个请求：重定向处理
        redirect_url = "https://www.codebuddy.ai/console/accounts/.apisix/redirect?state=b43b17cd7bced77b7513cd5c72b2894d&session_state=9b9a648a-867d-4d09-b00c-66b3e8bc650f&iss=https%3A%2F%2Fwww.codebuddy.ai%2Fauth%2Frealms%2Fcopilot&code=47711b3b-f234-4fe1-b91d-fd3d199638f9.9b9a648a-867d-4d09-b00c-66b3e8bc650f.3feb966c-1151-42a6-9619-5ac899a8ba88"
        
        print(f"\n📋 第二个请求 - 重定向处理:")
        print(f"  URL: {redirect_url}")
        
        redirect_params = parse_qs(urlparse(redirect_url).query)
        print("  参数:")
        for key, value in redirect_params.items():
            print(f"    - {key}: {value[0]}")
        
        # 第三个请求：最终访问
        final_url = "https://www.codebuddy.ai/console/accounts"
        print(f"\n📋 第三个请求 - 最终访问:")
        print(f"  URL: {final_url}")
        
        return {
            'login_url': login_url,
            'redirect_url': redirect_url,
            'final_url': final_url,
            'login_params': params,
            'redirect_params': redirect_params
        }
    
    def get_fresh_login_parameters(self):
        """获取新的登录参数"""
        print("\n🔄 获取新的登录参数...")
        
        try:
            # 访问控制台页面，触发重定向到登录页面
            console_url = "https://www.codebuddy.ai/console/accounts"
            response = self.session.get(console_url, allow_redirects=True)
            
            print(f"📊 状态码: {response.status_code}")
            print(f"🔗 最终URL: {response.url}")
            
            if "auth/realms/copilot" in response.url and "login-actions" in response.url:
                print("✅ 成功重定向到登录页面")
                
                # 解析URL获取新参数
                parsed_url = urlparse(response.url)
                params = parse_qs(parsed_url.query)
                
                print("🆕 获取到的新参数:")
                for key, value in params.items():
                    print(f"  - {key}: {value[0]}")
                
                return response.url, params
            else:
                print("❌ 未重定向到登录页面")
                return None, None
                
        except Exception as e:
            print(f"❌ 获取登录参数失败: {e}")
            return None, None
    
    def perform_complete_login(self, login_url):
        """执行完整的登录流程"""
        print(f"\n🚀 执行完整登录流程...")
        
        # 用户凭据
        username = "154hdgrkk7@dpmurt.my"
        password = "5gHpr0V!"
        
        print(f"👤 用户名: {username}")
        print(f"🔑 密码: {password}")
        
        # 步骤1: 执行登录认证
        print("\n📍 步骤1: 执行登录认证")
        
        login_data = "username=154hdgrkk7%40dpmurt.my&password=5gHpr0V%21&credentialId="
        
        login_headers = {
            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
            "accept-language": "zh-CN,zh;q=0.9",
            "cache-control": "max-age=0",
            "content-type": "application/x-www-form-urlencoded",
            "priority": "u=0, i",
            "sec-fetch-dest": "document",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "same-origin",
            "sec-fetch-user": "?1",
            "upgrade-insecure-requests": "1"
        }
        
        try:
            # 发送登录请求
            response1 = self.session.post(
                login_url,
                data=login_data,
                headers=login_headers,
                allow_redirects=True,
                timeout=30
            )
            
            print(f"  状态码: {response1.status_code}")
            print(f"  最终URL: {response1.url}")
            
            # 检查是否重定向到redirect URL
            if "redirect" in response1.url and "state" in response1.url:
                print("✅ 登录成功，重定向到授权码处理页面")
                
                # 步骤2: 处理重定向
                print("\n📍 步骤2: 处理授权码重定向")
                
                redirect_headers = {
                    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                    "accept-language": "zh-CN,zh;q=0.9",
                    "cache-control": "max-age=0",
                    "priority": "u=0, i",
                    "sec-fetch-dest": "document",
                    "sec-fetch-mode": "navigate",
                    "sec-fetch-site": "same-origin",
                    "sec-fetch-user": "?1",
                    "upgrade-insecure-requests": "1"
                }
                
                # 这里response1.url就是重定向URL，直接访问
                response2 = self.session.get(
                    response1.url,
                    headers=redirect_headers,
                    allow_redirects=True,
                    timeout=30
                )
                
                print(f"  状态码: {response2.status_code}")
                print(f"  最终URL: {response2.url}")
                
                # 步骤3: 访问最终页面
                print("\n📍 步骤3: 访问控制台页面")
                
                final_response = self.session.get(
                    "https://www.codebuddy.ai/console/accounts",
                    headers=redirect_headers,
                    allow_redirects=True,
                    timeout=30
                )
                
                print(f"  状态码: {final_response.status_code}")
                print(f"  最终URL: {final_response.url}")
                
                return self.analyze_login_success(final_response)
                
            else:
                print("❌ 登录失败，未重定向到预期页面")
                self.analyze_login_failure(response1)
                return False
                
        except Exception as e:
            print(f"❌ 登录流程异常: {e}")
            return False
    
    def analyze_login_success(self, response):
        """分析登录成功结果"""
        print("\n🔍 分析登录结果...")
        
        final_url = response.url.lower()
        response_text = response.text.lower()
        
        # 成功指标
        success_indicators = []
        
        if "console" in final_url:
            success_indicators.append("URL包含console")
        if "account" in final_url:
            success_indicators.append("URL包含account")
        if response.status_code == 200:
            success_indicators.append("HTTP 200状态码")
        if "logout" in response_text:
            success_indicators.append("页面包含logout")
        if "dashboard" in response_text or "控制台" in response_text:
            success_indicators.append("页面包含控制台内容")
        
        # 失败指标
        failure_indicators = []
        
        if "login" in final_url:
            failure_indicators.append("仍在登录页面")
        if "error" in final_url or "error" in response_text:
            failure_indicators.append("包含错误信息")
        if response.status_code >= 400:
            failure_indicators.append(f"HTTP {response.status_code}错误")
        
        print(f"✅ 成功指标 ({len(success_indicators)}):")
        for indicator in success_indicators:
            print(f"  - {indicator}")
        
        print(f"❌ 失败指标 ({len(failure_indicators)}):")
        for indicator in failure_indicators:
            print(f"  - {indicator}")
        
        # 显示cookies
        self.display_session_info()
        
        # 判断结果
        if len(success_indicators) > len(failure_indicators) and response.status_code == 200:
            print("\n🎉 登录成功！")
            return True
        else:
            print("\n❌ 登录失败")
            return False
    
    def analyze_login_failure(self, response):
        """分析登录失败原因"""
        print("\n❌ 登录失败分析:")
        print(f"  状态码: {response.status_code}")
        print(f"  最终URL: {response.url}")
        
        if response.status_code == 400:
            print("  原因: 请求参数错误（可能是session_code过期）")
        elif response.status_code == 401:
            print("  原因: 认证失败（用户名或密码错误）")
        elif response.status_code == 403:
            print("  原因: 访问被禁止")
        else:
            print("  原因: 未知错误")
    
    def display_session_info(self):
        """显示session信息"""
        print(f"\n🍪 Session信息:")
        if self.session.cookies:
            print(f"  获取到 {len(self.session.cookies)} 个cookies:")
            for cookie in self.session.cookies:
                print(f"    - {cookie.name}: {cookie.value[:30]}...")
        else:
            print("  未获取到cookies")
    
    def test_authenticated_access(self):
        """测试认证后的访问"""
        print("\n🔐 测试认证后访问...")
        
        test_urls = [
            "https://www.codebuddy.ai/console",
            "https://www.codebuddy.ai/console/accounts"
        ]
        
        for url in test_urls:
            try:
                response = self.session.get(url, allow_redirects=True, timeout=10)
                print(f"📊 {url}")
                print(f"  状态码: {response.status_code}")
                print(f"  最终URL: {response.url}")
                
                if response.status_code == 200 and "login" not in response.url.lower():
                    print(f"  ✅ 可以访问")
                else:
                    print(f"  ❌ 无法访问")
                    
            except Exception as e:
                print(f"  ❌ 测试失败: {e}")
    
    def run_complete_flow(self):
        """运行完整的登录流程"""
        print("=" * 60)
        print("🎯 CodeBuddy完整登录流程测试")
        print("=" * 60)
        
        # 分析提供的请求
        request_info = self.analyze_provided_requests()
        
        # 获取新的登录参数
        login_url, params = self.get_fresh_login_parameters()
        
        if login_url:
            # 执行完整登录流程
            success = self.perform_complete_login(login_url)
            
            if success:
                # 测试认证后访问
                self.test_authenticated_access()
                return True
        else:
            print("❌ 无法获取登录参数")
        
        return False

def main():
    """主函数"""
    print("🚀 开始CodeBuddy完整登录流程测试...")
    
    login_flow = CompleteLoginFlow()
    success = login_flow.run_complete_flow()
    
    print("\n" + "=" * 60)
    print("📋 完整流程测试结果")
    print("=" * 60)
    
    if success:
        print("✅ 完整登录流程测试成功！")
        print("🎯 结论:")
        print("  1. 用户凭据有效")
        print("  2. 登录流程正确")
        print("  3. 可以成功访问CodeBuddy控制台")
        print("\n💡 关键要点:")
        print("  - 需要实时获取session_code参数")
        print("  - 登录流程包含3个步骤：认证 → 重定向 → 最终访问")
        print("  - 必须保持session和cookies状态")
    else:
        print("❌ 完整登录流程测试失败！")
        print("🎯 可能原因:")
        print("  1. 网络连接问题")
        print("  2. 用户凭据已更改")
        print("  3. 网站结构发生变化")
        print("  4. 反自动化保护机制")

if __name__ == "__main__":
    main()